package com.xb.system.listener;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.xb.model.domain.CompanyData;
import com.xb.system.service.UsersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
public class ExcelDataThreadPoolListener extends AnalysisEventListener<CompanyData> {

    private final ExecutorService executorService;
    private final List<CompanyData> batchList = new CopyOnWriteArrayList<>();
    private final UsersService usersService;
    private final ExcelWriter excelWriter;
    private final WriteSheet writeSheet;
    private final Lock lock = new ReentrantLock();
    private final int BATCH_SIZE = 1000;

    public ExcelDataThreadPoolListener(UsersService usersService, String outputFilePath) {
        this.usersService = usersService;

        // 创建 ExcelWriter 实例和 WriteSheet 实例
        //获取outputFilePath的目录，但是outputFilePath是一个文件路径，只创建目录不需要文件名
        Path parent = Paths.get(outputFilePath).getParent();
        try {
            Files.createDirectories(parent);
            this.excelWriter = EasyExcel.write(outputFilePath, CompanyData.class).build();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建 ExcelWriter 实例和 WriteSheet 实例失败");
        }
        this.writeSheet = EasyExcel.writerSheet("Sheet1").build();

        // 创建固定大小的线程池
        this.executorService = Executors.newFixedThreadPool(10);
    }

    /**
     * 每读一行就会执行这个方法
     *
     * @param companyData
     * @param context
     */
    @Override
    public void invoke(CompanyData companyData, AnalysisContext context) {
        if (companyData.getPhone() == null || companyData.getPhone().trim().equals("")) {
            log.info(companyData.getRepresentative() + "没有手机号");
            companyData.setPhone("无");
        }
        batchList.add(companyData);
        if (batchList.size() >= BATCH_SIZE) {
            processCurrentBatch();
        }
    }

    /**
     * 所有数据读取完成后执行
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 处理剩余的批次
        if (!batchList.isEmpty() && batchList.size() < BATCH_SIZE) {
            processCurrentBatch();
        }
        executorService.shutdown();
        try {
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        // 处理完成后关闭 ExcelWriter
        excelWriter.finish();
    }

    private void processCurrentBatch() {
        List<CompanyData> batchToProcess;
        batchToProcess = new ArrayList<>(batchList);
        batchList.clear();
        executorService.submit(() -> processBatch(batchToProcess));
    }

    private void processBatch(List<CompanyData> batchToProcess) {
        List<CompanyData> outputList = new ArrayList<>();
        for (CompanyData companyData : batchToProcess) {
            processCompanyData(companyData, outputList);
        }
        // 写入数据时加锁
        lock.lock();
        try {
            excelWriter.write(outputList, writeSheet);
        } finally {
            lock.unlock();
        }
    }

    private void processCompanyData(CompanyData companyData, List<CompanyData> outputList) {
        // 从数据库中判断是否匹配
//        boolean matchFound = usersService.checkUserMatch(companyData.getPhone(), companyData.getRepresentative());
//        companyData.setMatchResult(matchFound ? 1 : 0);
//        outputList.add(companyData);
//        if (companyData.getMorePhones() != null) {
//            // 如果存在更多手机号，还有拿更多手机号去数据库中比较
//            for (String morePhone : companyData.getMorePhones().split("[，,;]")) {
//                if (!morePhone.matches("^1[3-9]\\d{9}$")) {
//                    continue;
//                }
//                boolean morePhoneMatch = usersService.checkUserMatch(morePhone.trim(), companyData.getRepresentative());
//                CompanyData morePhoneData = new CompanyData(morePhone.trim(), companyData.getCompanyName(), companyData.getRepresentative(), companyData.getMorePhones(), companyData.getNote1(), companyData.getNote2(), companyData.getNote3(), morePhoneMatch ? 1 : 0);
//                outputList.add(morePhoneData);
//            }
//        }
        String[] splitPhone = companyData.getPhone().trim().split("[,，;/\\s]");
        for (String phone : splitPhone) {
            boolean matchFound = usersService.checkUserMatch(phone, companyData.getRepresentative());
            CompanyData company = new CompanyData();
            BeanUtils.copyProperties(companyData, company);
            company.setMatchResult(matchFound ? 1 : 0);
            company.setPhone(phone);
            outputList.add(company);
            if (company.getMorePhones() != null) {
                // 如果存在更多手机号，还有拿更多手机号去数据库中比较
                for (String morePhone : company.getMorePhones().split("[,，;/\\s]")) {
                    if (!morePhone.matches("^1[3-9]\\d{9}$")) {
                        continue;
                    }
                    boolean morePhoneMatch = usersService.checkUserMatch(morePhone.trim(), company.getRepresentative());
                    CompanyData morePhoneData = new CompanyData(morePhone.trim(), company.getCompanyName(), company.getRepresentative(), companyData.getMorePhones(), companyData.getNote1(), companyData.getNote2(), companyData.getNote3(), morePhoneMatch ? 1 : 0);
                    outputList.add(morePhoneData);
                }
            }
        }
        
    }
}